/**
 * MacOSXConfiguraton.java 6 sept. 2006
 * 
 * Copyright (c) 2006 Emmanuel PUYBARET / eTeks <info@eteks.com>. All Rights
 * Reserved.
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.windu2b.jcaddie;

import java.awt.event.*;
import java.util.*;

import javax.swing.*;
import javax.swing.event.*;

import org.windu2b.jcaddie.model.*;
import org.windu2b.jcaddie.swing.*;

import com.apple.eawt.*;

/**
 * Configuration class that accesses to Mac OS X specifics. Do not invoke
 * methods of this class without checking first if <code>os.name</code> System
 * property is <code>Mac OS X</code>. This class requires some classes of
 * <code>com.apple.eawt</code> package to compile.
 * 
 * @author Emmanuel Puybaret, windu.2b
 */
public class MacOSXConfiguration
{
	private static Application	        application	= new Application();


	private static final ResourceBundle	RESOURCE	= ResourceBundle
	                                                        .getBundle( MacOSXConfiguration.class
	                                                                .getName() );


	private static CaddieController	    currentController;

	static
	{
		// Add a listener on Mac OS X application that will call
		// controller methods of the active frame
		application.addApplicationListener( new ApplicationAdapter()
		{
			@Override
			public void handleQuit( ApplicationEvent ev )
			{
				currentController.exit();
			}




			@Override
			public void handleAbout( ApplicationEvent ev )
			{
				currentController.about();
				ev.setHandled( true );
			}




			@Override
			public void handlePreferences( ApplicationEvent ev )
			{
				currentController.preferences();
			}




			@Override
			public void handleOpenFile( ApplicationEvent ev )
			{
				// handleOpenFile is called when user opens a document
				// associated with a Java Web Start application
				// Just call main with -open file arguments as JNLP specifies
				JCaddie.main( new String[] { "-open", ev.getFilename() } );
			}
		} );

		application.setEnabledAboutMenu( true );
		application.setEnabledPreferencesMenu( true );
	}




	/**
	   * Binds the caddie <code>controller</code> methods of a <code>frame</code>
	   * to Mac OS X application menu.
	   */
	public static void bindControllerToApplicationMenu( final JFrame frame,
	        final CaddieController controller )
	{
		frame.addWindowListener( new WindowAdapter()
		{
			@Override
			public void windowActivated( WindowEvent ev )
			{
				currentController = controller;
			}
		} );
	}




	/**
	 * Binds <code>caddieApplication</code> to Mac OS X application menu.
	 */
	/*public static void bindToApplicationMenu( final Main caddieApplication )
	{
		// Create a default controller for an empty caddie and disable unrelated
		// actions
		final CaddieController defaultController = new CaddieController(
		        new Caddie(), caddieApplication );
		CaddiePane defaultCaddieView = ( CaddiePane ) defaultController
		        .getView();
		defaultCaddieView.setEnabled( CaddiePane.ActionType.CLOSE, false );
		defaultCaddieView.setEnabled( CaddiePane.ActionType.SAVE, false );
		defaultCaddieView.setEnabled( CaddiePane.ActionType.SAVE_AS, false );

		// Create a default undecorated frame out of sight
		// and attach the application menu bar of empty view to it
		JFrame defaultFrame = new JFrame();
		defaultFrame.setLocation( -10, 0 );
		defaultFrame.setUndecorated( true );
		defaultFrame.setVisible( true );
		defaultFrame.setJMenuBar( defaultCaddieView.getJMenuBar() );
		addWindowMenuToFrame( defaultFrame, caddieApplication, true );

		Application application = new Application();
		// Add a listener on Mac OS X application that will call
		// controller methods of the active frame
		application.addApplicationListener( new ApplicationAdapter()
		{
			@Override
			public void handleQuit( ApplicationEvent ev )
			{
				defaultController.exit();
				if ( caddieApplication.getCaddies().isEmpty() )
				{
					System.exit( 0 );
				}
			}




			@Override
			public void handleAbout( ApplicationEvent ev )
			{
				defaultController.about();
				ev.setHandled( true );
			}




			@Override
			public void handlePreferences( ApplicationEvent ev )
			{
				defaultController.editPreferences();
			}




			@Override
			public void handleOpenFile( ApplicationEvent ev )
			{
				// handleOpenFile is called when user opens a document
				// associated with a Java Web Start application
				// Just call main with -open file arguments as JNLP specifies
				Main.main( new String[] { "-open", ev.getFilename() } );
			}




			@Override
			public void handleReOpenApplication( ApplicationEvent ev )
			{
				// handleReOpenApplication is called when user launches
				// the application when it's already open
				Main.main( new String[0] );
			}
		} );
		application.setEnabledAboutMenu( true );
		application.setEnabledPreferencesMenu( true );

		caddieApplication.addCaddieListener( new CaddieListener()
		{
			public void caddieChanged( CaddieEvent ev )
			{
				if ( ev.getType() == CaddieEvent.Type.ADD )
				{
					// Add Mac OS X Window menu on new caddies
					MacOSXConfiguration.addWindowMenuToFrame( caddieApplication
					        .getCaddieFrame( ev.getCaddie() ),
					        caddieApplication, false );
				}
			};
		} );
	}*/




	/**
	 * Adds Mac OS X standard Window menu to frame.
	 * 
	 * @param application
	 */
	private static void addWindowMenuToFrame( final JFrame frame,
	        final Main application, boolean defaultFrame )
	{
		final JMenu windowMenu = new JMenu( new ResourceAction( RESOURCE,
		        "WINDOW", true ) );
		frame.getJMenuBar().add( windowMenu );
		windowMenu.add( new JMenuItem( new ResourceAction( RESOURCE,
		        "MINIMIZE", !defaultFrame )
		{
			/**
			 * 
			 */
			private static final long	serialVersionUID	= -5817990425562321996L;




			public void actionPerformed( ActionEvent ev )
			{
				frame.setState( JFrame.ICONIFIED );
			}
		} ) );
		windowMenu.add( new JMenuItem( new ResourceAction( RESOURCE, "ZOOM",
		        !defaultFrame )
		{
			/**
			 * 
			 */
			private static final long	serialVersionUID	= 2948161447173113655L;




			public void actionPerformed( ActionEvent ev )
			{
				if ( ( frame.getExtendedState() & JFrame.MAXIMIZED_BOTH ) != 0 )
				{
					frame.setExtendedState( frame.getExtendedState()
					        & ~JFrame.MAXIMIZED_BOTH );
				}
				else
				{
					frame.setExtendedState( frame.getExtendedState()
					        | JFrame.MAXIMIZED_BOTH );
				}
			}
		} ) );
		windowMenu.addSeparator();
		windowMenu.add( new JMenuItem( new ResourceAction( RESOURCE,
		        "BRING_ALL_TO_FRONT", !defaultFrame )
		{
			/**
			 * 
			 */
			private static final long	serialVersionUID	= 3533503161533247342L;




			public void actionPerformed( ActionEvent ev )
			{
				// Avoid blincking while bringing other windows to front
				frame.setAlwaysOnTop( true );
				for ( Caddie caddie : application.getCaddies() )
				{
					JFrame applicationFrame = application
					        .getCaddieFrame( caddie );
					if ( applicationFrame != frame
					        && applicationFrame.getState() != JFrame.ICONIFIED )
					{
						applicationFrame.setFocusableWindowState( false );
						applicationFrame.toFront();
						applicationFrame.setFocusableWindowState( true );
					}
				}
				frame.setAlwaysOnTop( false );
			}
		} ) );

		windowMenu.addMenuListener( new MenuListener()
		{
			public void menuSelected( MenuEvent ev )
			{
				boolean firstMenuItem = true;
				// Fill menu dynamically with a menu item for the frame of each
				// application caddie
				for ( Caddie caddie : application.getCaddies() )
				{
					final JFrame applicationFrame = application
					        .getCaddieFrame( caddie );
					JCheckBoxMenuItem windowMenuItem = new JCheckBoxMenuItem(
					        new AbstractAction( applicationFrame.getTitle() )
					        {
						        /**
								 * 
								 */
						        private static final long	serialVersionUID	= 4078010220134649679L;




						        public void actionPerformed( ActionEvent ev )
						        {
							        applicationFrame.toFront();
						        }
					        } );

					if ( frame == applicationFrame )
					{
						windowMenuItem.setSelected( true );
					}
					if ( firstMenuItem )
					{
						windowMenu.addSeparator();
						firstMenuItem = false;
					}
					windowMenu.add( windowMenuItem );
				}
			}




			public void menuDeselected( MenuEvent ev )
			{
				// Remove dinamically filled part of menu
				for ( int i = windowMenu.getMenuComponentCount() - 1; i >= 4; i-- )
				{
					windowMenu.remove( i );
				}
			}




			public void menuCanceled( MenuEvent ev )
			{
				menuDeselected( ev );
			}
		} );
	}
}